<?php namespace Hdphp\View;

use Hdphp\View\Compile;
use Exception;
//视图处理
class View{
	
	//模板变量集合
	protected $vars = array();

    //模版文件
	public $tpl;
	
	//编译文件
	public $compile;

	public function __construct(){
  }

    /**
     * 解析模板
     * @param  [type]  $tpl  [description]
     * @param  string  $data [description]
     * @param  boolean $show [description]
     * @return [type]        [description]
     */
    public function make($tpl='',$expire=-1,$show=true)
    {
      //模板文件
      $this->tpl = $this->getTemplateFile($tpl);
      //缓存文件
      $cache = md5($_SERVER['REQUEST_URI']).'.php';

      //编译文件
      $this->compile= 'storage/view/compile/'.md5($this->tpl).'.php';

      //缓存有效
      if($expire>0 && $content = Cache::dir('storage/view/cache')->get($cache))
      {
        if($show)
        {
          die($content);
        }
        else
        {
          return $content;
        }
      }
      
      //检测模板文件合法性
      if(!$this->checkFile())
      {
        throw new Exception($this->tpl."模板不存在");
      }

        //编译文件
      $this->compileFile();

      //释放变量到全局
      if(!empty($this->vars))
      {
        extract($this->vars);
      }
      //获取解析结果
      ob_start();
      require($this->compile);
      $content =  ob_get_clean();

      if($expire>0)
      {
        //缓存
        if(!Cache::dir('storage/view/cache')->set($cache,$content,$expire))
        {
          throw new Exception("创建缓存失效");
        }
      }

      if($show)
      {
        echo $content;
      }
      else
      {
        return $content;
      }
    }

  /**
   * 获取模板文件
   * @param  [type] $tpl [description]
   * @return [type]      [description]
   */
  private function getTemplateFile($file)
  {
    if(!defined('MODULE'))
    { 
      //路由中使用回调函数执行View::make()时，因为没有MODULE
      $file = C('view.path').'/'.$file;
    }
    else
    {
    //模块视图文件夹
      $viewPath = strstr(C('view.path'),'/')?C('view.path'):(MODULE_PATH.'/'.C('view.path')).'/'.CONTROLLER;

      if (empty($file))
      {
        $file = $viewPath.'/' . ACTION;
      }
      else if(!strstr($file, '/'))
      {
        $file = $viewPath.'/'. $file;
      }
    }
    
    $file .= C('view.prefix');
    //判断文件
    if (is_file($file))
    {
      return $file;
    }
    else
    {
      throw new Exception("模板不存在:$file");
      return false;
    }
  }

  //验证缓存文件
  public function isCache()
  {
    $cache = md5($_SERVER['REQUEST_URI']).'.php';
    return Cache::dir('storage/view')->get($cache);
  }

	/**
	 * 检测模板文件合法性
	 */
	private function checkFile()
	{
		return is_file($this->tpl) && is_readable($this->tpl);
	}

	/**
	 * 验证编译文件
	 * @return [type] [description]
	 */
	private function compileFile()
	{
		$status = !DEBUG && file_exists($this->compile) && (filemtime($this->compile)>filemtime($this->tpl));

		if(!$status)
		{
			//执行文件编译
      $compile = new Compile($this);
      $compile->run();
    }
  }

	/**
	 * 分配变量
	 * @param  [type] $name  [description]
	 * @param  [type] $value [description]
	 * @return [type]        [description]
	 */
	public function with($name,$value='')
	{
    if(is_array($name))
    {
      foreach($name as $k=>$v)
      {
        $this->vars[$k]=$v; 
      }
    }
    else
    {
      $this->vars[$name]=$value; 
    }

    return $this;
  }

    /**
     * 错误页面
     * @param string $message 提示内容
     * @param null $url 跳转URL
     * @param int $time 跳转时间
     * @param null $tpl 模板文件
     */
    public function error($message = '出错了', $url = NULL, $time = 2, $tpl = null)
    {
      $url = $url ? "window.location.href='" . U($url) . "'" : "window.location.href='" . __HISTORY__ . "'";

      $tpl = $tpl ? $tpl : Config::get('view.error');

      $this->with(array('message' => $message, 'url' => $url, 'time' => $time));
      $this->make($tpl);
      exit;
    }

    /**
     * 成功页面
     * @param string $message 提示内容
     * @param null $url 跳转URL
     * @param int $time 跳转时间
     * @param null $tpl 模板文件
     */
    public function success($message = '操作成功', $url = null, $time = 2, $tpl = null)
    {
      $url = $url ? "window.location.href='" . U($url) . "'" : "window.location.href='" . __HISTORY__ . "'";

      $tpl = $tpl ? $tpl : Config::get('view.success');

      $this->with(array('message' => $message, 'url' => $url, 'time' => $time));
      $this->make($tpl);
      exit;
    }

    /**
     * Ajax输出
     * @param $data 数据
     * @param string $type 数据类型 text html xml json
     */
    public function ajax($data, $type = "JSON")
    {
      Response::ajax($data,$type);
    }
  }